import FYAudioMgr from '../Frame/Audio/FYAudioMgr';
import FYLog from '../Frame/FYLog';
import FYMessenger from '../Frame/FYMessenger';
import FYGlobalVarMgr from '../Global/FYGlobalVarMgr';
import { EnumSDK } from './EnumSDK';
import FYPlatformMgr from './FYPlatformMgr';
import FYSDKConfig from './FYSDKConfig';

/** CocosCreator微信小游戏SDK管理器 */
export default class TTSDK {
    public static readonly Instance: TTSDK = new TTSDK();
    private constructor() { }

    public static readonly AppID: string = FYSDKConfig.appid;
    /** 分享群ID */
    public SaveKeyShareGroupIds = TTSDK.AppID + "SaveKeyShareGroupIds";

    /** 客户端平台 */
    public static platform = "";
    /** 操作系统版本 */
    public static system = "";

    /** 分享回调 */
    public static listShareCB = [];

    public static shareStartTime = 0;

    /** banner 字典 */
    public static dictBanner: { [key: string]: tt.banner } = {};

    /** banner底部偏移值 */
    public static bannerBottomDelta = 0;

    /** 振动开关 */
    public static shakeSwitch = true;


    /** 录屏地址 */
    private recordPath: string = "";
    /** 录屏标题 */
    private recordTitle: string = "";
    /** 录屏描述 */
    private recordDesc: string = "";
    /** 录屏时间 */
    private recordTime: number = 0;
    /** 录屏是否不弹提示 */
    private recordNoTip: boolean = false;
    /** 是否正在录制 */
    private isRecording: boolean = false;

    /** 分享模板编号 */
    private shareTemplateId: string = "3so14xo2h0t5hfjh6f";

    public init(cbOnShow: (res) => void, cbOnHide: () => void, ) {
        if (FYPlatformMgr.isTT()) {
            // 显示转发按钮
            if (tt.showShareMenu) {
                tt.showShareMenu({ withShareTicket: true });
            }
            // 转发样式
            //let _path = FYSDKMgr.Instance.Md5Pipe(CCCWXMiniGameSDKMgr.Instance.SharePicPath);


            if (tt.onShareAppMessage) {
                tt.onShareAppMessage((res) => {
                    return {
                        templateId: this.shareTemplateId,
                    }
                });
            }

            // 游戏回到前台
            if (tt.onShow) {
                tt.onShow((res) => {
                    if (cbOnShow != null) {
                        cbOnShow(res);
                    }
                })
            }

            // 游戏回到后台
            if (tt.onHide) {
                tt.onHide(() => {
                    if (cbOnHide != null) {
                        cbOnHide();
                    }
                });
            }

            // 获取系统信息
            if (tt.getSystemInfo) {
                tt.getSystemInfo({
                    success: (res) => {
                        TTSDK.platform = res.platform;
                        TTSDK.system = res.system;
                    }
                });
            }

            // 当内存不足 调用释放
            if (tt.onMemoryWarning) {
                tt.onMemoryWarning(() => {
                    FYLog.log('onMemoryWarningReceive');
                    if (tt.triggerGC) {
                        tt.triggerGC();
                    }
                });
            }

            // 校验是否有新版本
            this.checkUpdate();

            // 保存录屏地址
            if (tt.getGameRecorderManager) {
                let gameRecorder = tt.getGameRecorderManager();
                gameRecorder.onStart(() => {
                    console.log("录屏开始onStart");
                    this.recordTime = new Date().getTime();
                    this.recordNoTip = false;
                    // tt.showToast({ title: "开始录制", icon: "none" });

                    this.recordPath = "";
                });

                gameRecorder.onStop((res) => {
                    if (new Date().getTime() - this.recordTime < 3000) {
                        if (!this.recordNoTip) {
                            // 录屏时间低于 3 秒，请提示"录屏失败：录屏时长低于 3 秒"
                            tt.showToast({ title: "录屏失败：录屏时长低于3秒", icon: "none" });
                        }
                    } else {
                        console.log("录屏地址" + this.recordPath);
                        this.recordPath = res.videoPath;
                        if (!this.recordNoTip) {
                            // tt.showToast({ title: "录制完成", icon: "none" });
                        }

                        FYMessenger.Instance.send(EnumSDK.MsgType.RecordEnd);
                    }
                });
            }
        }
    }

    /**
     * 只有开放数据域能调用，获取主域和开放数据域共享的 sharedCanvas
     */
    public wxGetSharedCanvas() {
        if (FYPlatformMgr.isTT() && tt.getSharedCanvas) {
            try {
                return tt.getSharedCanvas();
            } catch (error) {
                return null;
            }
        }
    }

    /**
     * 主域程序向子域程序发送。
     * 
     * exsample： FYSDKMgr.Instance.wxPostMessage(C.ToChildProgramMsgName.ShowRank, [{id: id}]);
     * @param obj 参数
     */
    public wxPostMessage(req: string, args) {
        //FYLog.log("----------post--", req)
        if (FYPlatformMgr.isTT() && tt.getOpenDataContext) {
            try {
                let openDataContext = tt.getOpenDataContext()
                openDataContext.postMessage({
                    req: req,
                    data: args,
                });
            } catch (error) {
                FYLog.error(error);
            }
        }
    }

    /**
     * 创建游戏圈按钮
     * @param posX x坐标
     * @param posY y坐标
     * @param width 宽度
     * @param height 高度
     */
    public wxCreateGameClubButton(posX: number, posY: number, width: number, height: number): tt.GameClubButton {
        if (FYPlatformMgr.isTT() && tt.getSystemInfoSync && tt.createGameClubButton) {
            try {
                let screenWidth = tt.getSystemInfoSync().screenWidth;
                let radio = FYGlobalVarMgr.Instance.WinSize.width / screenWidth;

                let wxPosx = TTSDK.Instance.cccPosXToTTPosX(posX - width / 2);
                let wxPosY = TTSDK.Instance.cccPosYToTTPosY(posY + height / 2);

                let button = tt.createGameClubButton({
                    icon: 'green',
                    style: {
                        left: wxPosx,
                        top: wxPosY,
                        width: width / radio,
                        height: height / radio
                    }
                });
                return button
            } catch (error) {
                FYLog.error(error);
                return null;
            }

        }
    }

    /**
     * 判断是否可以使用广告
     */
    public isAds() {
        // try {
        //     let sysInfo = tt.getSystemInfoSync();
        //     let sdkVer = sysInfo.SDKVersion;
        //     if (sdkVer >= "2.0.4") {
        //         return true;
        //     }
        //     return false;
        // } catch (error) {
        //     FYLog.error(error);
        //     return false;
        // }
        return true;
    }

    /**
     * 创建广告
     */
    public createAd(sAdUnitId) {
        if (FYPlatformMgr.isTT() && this.isAds() && tt.createRewardedVideoAd) {
            try {
                let videoAd = tt.createRewardedVideoAd({
                    adUnitId: sAdUnitId,
                });
                return videoAd;
            } catch (error) {
                FYLog.error(error);
                return null;
            }
        }
    }

    /**
     * 显示广告
     * @param closeCallBack 播放结束回调（bool：是否正常播放完成）
     */
    public showAd(closeCallBack: (isEnded: boolean) => void, sAdUnitId) {
        if (FYPlatformMgr.isTT()) {
            FYLog.log("----------创建视频广告-------", sAdUnitId);
            let videoAd = this.createAd(sAdUnitId);
            if (videoAd) {
                videoAd.load().then(
                    () => {
                        FYAudioMgr.Instance.pauseMusic();
                        videoAd.show();
                    }
                ).catch(err => FYLog.log(err.errMsg));
                let func = function (status) {
                    FYLog.log("------fysdk----播放回调-------", status)
                    if (status && status.isEnded || status == undefined) {
                        if (closeCallBack) {
                            closeCallBack(true);
                        }
                    } else {
                        if (closeCallBack) {
                            closeCallBack(false);
                        }
                    }
                    try {
                        videoAd.offClose(func);
                        videoAd.offError();
                    } catch (error) {

                    }

                    FYAudioMgr.Instance.resumePre();
                }
                videoAd.onClose(func);
                videoAd.onError(function (err) {
                    FYLog.log("========广告加载失败===========", err, "sAdUnitId = ", sAdUnitId)
                    FYAudioMgr.Instance.resumePre();
                    if (closeCallBack) {
                        closeCallBack(false);
                    }
                    tt.showToast({
                        title: "广告加载失败! " + err,
                        icon: "none",
                    });

                    try {
                        videoAd.offClose(func);
                        videoAd.offError();
                    } catch (error) {

                    }
                });
            }
        } else {
            if (closeCallBack) {
                closeCallBack(true);
            }
        }
    }

    /**
     * 分享
     */
    public shareAppMessage() {
        if (FYPlatformMgr.isTT() && tt.shareAppMessage) {
            let self = this;
            let param = {
                templateId: this.shareTemplateId,
            }
            tt.shareAppMessage(param);
        }
    }

    /**
     * 
     * @param sAdUnitId 创建Banner位
     */
    public showBannerAd(sAdUnitId, onError = null, onResize = null) {
        if (FYPlatformMgr.isTT() && tt.getSystemInfoSync && tt.createBannerAd) {
            let systemInfo = tt.getSystemInfoSync();
            let screenHeight = systemInfo.screenHeight;
            let screenWidth = systemInfo.screenWidth;
            let radio = screenHeight / cc.winSize.height;
            FYLog.log("screenHeight = " + screenHeight + " screenWidth = " + screenWidth);
            // Banner广告一般的比例为16:9，最小宽度是128（设备像素），最大宽度是208（设备像素）
            let targetBannerAdWidth = screenWidth;

            let bannerAd = TTSDK.dictBanner[sAdUnitId];
            if (bannerAd) {
                bannerAd.show();
            } else {
                try {
                    FYLog.log("---> AppName = " + systemInfo.appName);
                    if (systemInfo.appName == "Toutiao" || systemInfo.appName == "lite") {
                        bannerAd = tt.createBannerAd({
                            adUnitId: sAdUnitId,
                            adIntervals: 30,
                            style: {
                                width: targetBannerAdWidth,
                                top: screenHeight - (targetBannerAdWidth / 16 * 9 * radio), // 根据系统约定尺寸计算出广告高度
                            },
                        });

                        if (bannerAd) {
                            bannerAd.style.left = (screenWidth - targetBannerAdWidth) / 2;

                            bannerAd.onResize(res => {
                                FYLog.log(res.width, res.height);
                                // 如果一开始设置的 banner 宽度超过了系统限制，可以在此处加以调整
                                if (targetBannerAdWidth != res.width) {
                                    targetBannerAdWidth = res.width;
                                    bannerAd.style.top = screenHeight - (res.width / 16 * 9 * radio);
                                    bannerAd.style.left = (screenWidth - res.width) / 2;
                                }
                            });
                            bannerAd.onError(() => {
                                FYLog.log("----Banner 加载失败-------")
                                if (bannerAd) {
                                    bannerAd.offError();
                                }
                                if (onError) {
                                    onError();
                                }
                                if (bannerAd) {
                                    bannerAd.destroy();
                                    TTSDK.dictBanner[sAdUnitId] = null;
                                }
                            });
                            bannerAd.onLoad(() => {
                                FYLog.log("----Banner 加载成功-------");
                                FYLog.log("---Banner left = " + bannerAd.style.left + " Banner top = " + bannerAd.style.top + " Banner width = " + bannerAd.style.width + " Banner height = " + bannerAd.style.height);

                                if (TTSDK.dictBanner[sAdUnitId]) {
                                    TTSDK.dictBanner[sAdUnitId].destroy();
                                }
                                TTSDK.dictBanner[sAdUnitId] = bannerAd;
                                TTSDK.dictBanner[sAdUnitId].show();
                            });
                        }
                    }
                } catch (error) {
                    FYLog.log(error);
                }
            }
        }
    }

    public hideBannerId(sAdUnitId) {
        let bannerAd = TTSDK.dictBanner[sAdUnitId];
        if (bannerAd) {
            bannerAd.hide();
        }
    }

    /**
     * 跳转到指定小程序
     * @param appId 小程序APPID
     */
    public navigateToMiniProgram(appId: string, successCB?: Function, failCB?: Function, path = "", extraData = "", envVersion = "release") {
        if (FYPlatformMgr.isTT() && tt.navigateToMiniProgram) {
            tt.navigateToMiniProgram({
                appId: appId,
                path: path,
                extraData: extraData,
                envVersion: envVersion,
                success: successCB,
                fail: failCB
            })
        }
    }

    /**
     * 打开客服
     */
    public openCustomerServiceConversation() {
        if (FYPlatformMgr.isTT() && tt.openCustomerServiceConversation) {
            tt.openCustomerServiceConversation({ sessionFrom: "" });
        }
    }

    public getMenuButtonBoundingClientRect(): tt.MenuButtonBoundingClientRect {
        if (FYPlatformMgr.isTT()) {
            try {
                let rect = tt.getMenuButtonBoundingClientRect ? tt.getMenuButtonBoundingClientRect() : null;
                if (!rect) {
                    throw new Error('getMenuButtonBoundingClientRect error');
                }
                return tt.getMenuButtonBoundingClientRect();
            } catch (err) {
                // 赋默认数值
                if (FYGlobalVarMgr.Instance.WinSize.height / FYGlobalVarMgr.Instance.WinSize.width > 2.1) {
                    // 刘海屏
                    return {
                        bottom: 76,
                        left: 278,
                        right: 365,
                        top: 44,
                        height: 32,
                        width: 87,
                    }
                } else {
                    return {
                        bottom: 42,
                        left: 317,
                        right: 404,
                        top: 10,
                        height: 32,
                        width: 87,
                    }
                }
            }
        }
    }

    /**
     * 微信的坐标系原点在左上角
     */

    /**
     * 微信Y坐标转CocosCreator
     * @param wxPosY 微信的Y坐标
     */
    ttPosYToCCCPosY(wxPosY) {
        if (FYPlatformMgr.isTT() && tt.getSystemInfoSync) {
            let screenWidth = tt.getSystemInfoSync().screenWidth;
            let radio = FYGlobalVarMgr.Instance.WinSize.width / screenWidth;
            let CCCPosY = FYGlobalVarMgr.Instance.WinSize.height / 2 - wxPosY * radio;
            return CCCPosY;
        } else {
            return 0;
        }
    }

    /**
     * 微信Y坐标转CocosCreator
     * @param wxPosY 微信的X坐标
     */
    ttPosYToCCCPosX(wxPosX) {
        if (FYPlatformMgr.isTT() && tt.getSystemInfoSync) {
            let screenWidth = tt.getSystemInfoSync().screenWidth;
            let radio = FYGlobalVarMgr.Instance.WinSize.width / screenWidth;
            let CCCPosX = -FYGlobalVarMgr.Instance.WinSize.width / 2 + wxPosX * radio;
            return CCCPosX;
        } else {
            return 0;
        }
    }

    /**
     * CocosCreator Y坐标转微信Y坐标
     * @param cccPosY CocosCreator Y坐标
     */
    cccPosYToTTPosY(cccPosY) {
        if (FYPlatformMgr.isTT() && tt.getSystemInfoSync) {
            let screenWidth = tt.getSystemInfoSync().screenWidth;
            let radio = FYGlobalVarMgr.Instance.WinSize.width / screenWidth;

            let wxPosY = (FYGlobalVarMgr.Instance.WinSize.height / 2 - cccPosY) / radio;
            return wxPosY;
        } else {
            return 0;
        }
    }

    /**
     * CocosCreator X坐标转微信X坐标
     * @param cccPosX CocosCreator X坐标
     */
    cccPosXToTTPosX(cccPosX) {
        if (FYPlatformMgr.isTT() && tt.getSystemInfoSync) {
            let screenWidth = tt.getSystemInfoSync().screenWidth;
            let radio = FYGlobalVarMgr.Instance.WinSize.width / screenWidth;

            let wxPosX = (cccPosX + FYGlobalVarMgr.Instance.WinSize.width / 2) / radio;
            return wxPosX;
        } else {
            return 0;
        }
    }

    /**
     * 水平对齐微信的菜单
     * @param nodeTarget 目标对象 锚点Y 改成1
     */
    alignToMenu(nodeTarget: cc.Node) {
        if (FYPlatformMgr.isTT() && tt.getSystemInfoSync) {
            let screenWidth = tt.getSystemInfoSync().screenWidth;
            // let radio = FYGlobalVarMgr.Instance.WinSize.width / screenWidth;
            nodeTarget.y = TTSDK.Instance.ttPosYToCCCPosY(TTSDK.Instance.getMenuButtonBoundingClientRect().top + TTSDK.Instance.getMenuButtonBoundingClientRect().height / 2);
        }
    }

    /**
     * 校验是否有更新
     */
    checkUpdate() {
        if (FYPlatformMgr.isTT() && tt.getUpdateManager && tt.showModal) {

            let updateManager = tt.getUpdateManager();
            updateManager.onCheckForUpdate(function (res) {
                // 请求完新版本信息的回调
                FYLog.log(res.hasUpdate);
            });

            updateManager.onUpdateReady(function () {
                tt.showModal({
                    title: '更新提示',
                    content: '新版本已经准备好，是否重启应用？',
                    success: function (res) {
                        if (res.confirm) {
                            // 新的版本已经下载好，调用 applyUpdate 应用新版本并重启
                            updateManager.applyUpdate();
                        }
                    }
                });
            });

            updateManager.onUpdateFailed(function () {
                // 新版本下载失败
            });
        }
    }

    //#region 录屏相关API

    /**
     * 开始录屏
     * @param duration 录屏的时长，单位 s，必须大于 3s，最大值 300s（5 分钟）
     */
    public recordStart(duration: number) {
        if (FYPlatformMgr.isTT() && !this.isRecording && tt.getGameRecorderManager) {
            this.isRecording = true;
            let gameRecorder = tt.getGameRecorderManager();
            gameRecorder.start({ "duration": duration });
            console.log("开始录屏");
        }
    }

    /**
     * 录屏停止
     * @param isNoTips 是否显示录制失败提示
     */
    public recordStop(isNoTips = false) {
        if (FYPlatformMgr.isTT() && this.isRecording && tt.getGameRecorderManager) {
            this.isRecording = false;
            let gameRecorder = tt.getGameRecorderManager();
            this.recordNoTip = isNoTips;
            gameRecorder.stop();
            FYLog.log("录屏结束");
        }
    }

    /**
     * 录屏分享
     */
    public recordShare(success?: Function, fail?: Function) {
        if (FYPlatformMgr.isTT() && tt.shareAppMessage) {
            if (this.recordPath == "") {
                tt.showToast({ title: "请先录制，后分享", icon: "none" });
                return;
            }
            FYLog.log("分享录屏地址 " + this.recordPath);
            tt.shareAppMessage({
                channel: "video",
                templateId: this.shareTemplateId,
                extra: {
                    videoPath: this.recordPath,
                },
                success() {
                    if (success) {
                        success();
                    }
                },
                fail() {
                    if (fail) {
                        fail();
                    }
                }
            });
        }
    }

    //#endregion
}
